#pragma once

#include <vector>
#include <string>
#include <functional>
#include <iostream>
#include <memory>

#define CHAR_BUFFER_SIZE 256

class File;
class Context;
struct FileInfoStruct
{
	char type = ' ';
	std::string filePath;
	std::string fileName;
	std::string fileName_optimized; // optimized for search => insensitivecase
	std::string ext;
	size_t fileSize = 0; // for sorting operations
	std::string formatedFileSize;
	std::string fileModifDate;
};

class FileSystem
{
public:
	explicit FileSystem(Context* context);
	virtual ~FileSystem();

	bool FileExists(const std::string& fileName) const;

	std::shared_ptr<File> GetFile(const std::string& path, bool fullPath = false);

	void addSearchePath(std::string path);
	std::string OptimizeToLow(std::string vFileName);
	void FillInfos(FileInfoStruct* vFileInfoStruct);
	void ListFiles(const char* path, std::vector<FileInfoStruct>& listOut);
	void ListFiles(const char* path, std::function<void(const FileInfoStruct&)>);
	void ListRelativeFiles(const char* path, std::vector<FileInfoStruct>& listOut);
	std::string GetCurrentDir();

	std::string GetUserDocumentsDir() const;

	bool CreateDir(std::string path);
	bool DirExists(const std::string& pathName) const;

	static std::string Sep;
private:
	std::vector<std::string> allowedPaths_{};
	Context* context_{ nullptr };
};

extern std::string string_trimmed(std::string& scource);
extern int string_replase(std::string& s1, const std::string& s2, const std::string& s3);
extern std::string GetNativePath(const std::string& pathName);
extern std::string GetFileName(std::string& path);
extern std::string PathJoin(const std::vector<std::string>& paths);

